/**
 * 作者: 会写BUG
 * 创作日期: 2025/3/21 09:37
 * 描述: cwbQtPractice.GameWindow
 *
 **/

#include "game_window.h"
#include "chess_panel.h"
#include "display_panel.h"
#include "about_panel.h"
#include "score_record.h"

#include <QVBoxLayout>
#include <QPainter>
#include <QSequentialAnimationGroup>

#include "menu_panel.h"

GameWindow::GameWindow(QWidget *parent) 
    : QDialog(parent) {

    initUI();
    initConnect();
}

GameWindow::~GameWindow() = default;

void GameWindow::initUI()
{
    chess_panel_ = new ChessPanel();
    display_panel_ = new DisplayPanel();
    about_panel_ = new AboutPanel();
    center_stacked_ = new QStackedWidget();

    auto main_layout = new QVBoxLayout(this);
    main_layout->setSpacing(0);
    main_layout->setContentsMargins(50, 100, 50, 100);
    main_layout->addWidget(center_stacked_);

    QWidget * center_widget = new QWidget();
    QVBoxLayout * game_layout = new QVBoxLayout(center_widget);
    game_layout->setSpacing(0);
    game_layout->setContentsMargins(0, 0, 0, 0);
    game_layout->addWidget(display_panel_, 1);
    game_layout->addWidget(chess_panel_, 2);

    center_stacked_->addWidget(center_widget);
    center_stacked_->addWidget(about_panel_);

}

void GameWindow::initConnect()
{
    connect(display_panel_->menuPanel(), &MenuPanel::aboutGame,
        this, &GameWindow::aboutGame);
}

void GameWindow::aboutGame()
{
    /* 关于界面的动画
     * 1 将当前界面往中间收拢
     * 2 将关于界面从中间往两边展开
     */
    int next_index = center_stacked_->currentIndex() == center_stacked_->count() - 1? center_stacked_->currentIndex() - 1 : center_stacked_->currentIndex() + 1;

    QRect current_rect = center_stacked_->geometry();
    QRect target_rect = QRect(center_stacked_->geometry().width() * 0.5 - 2, center_stacked_->geometry().y(),
       2,center_stacked_->geometry().height());

    /* 串行动画 */
    QSequentialAnimationGroup * animation_group = new QSequentialAnimationGroup(this);

    QPropertyAnimation * animation = new QPropertyAnimation(center_stacked_, "geometry");
    animation->setDuration(200);
    animation->setStartValue(current_rect);
    animation->setEndValue(target_rect);
    animation->setEasingCurve(QEasingCurve::InQuad);
    animation_group->addAnimation(animation);
    connect(animation, &QPropertyAnimation::valueChanged,this, [=](const QVariant &value)
    {
        update();
    });

    animation = new QPropertyAnimation(center_stacked_, "geometry");
    animation->setDuration(200);
    animation->setStartValue(target_rect);
    animation->setEndValue(current_rect);
    animation->setEasingCurve(QEasingCurve::InQuad);
    animation_group->addAnimation(animation);
    connect(animation, &QPropertyAnimation::valueChanged,this, [=](const QVariant &value)
    {
        update();
    });

    connect(animation_group, &QSequentialAnimationGroup::currentAnimationChanged,this, [=](QAbstractAnimation * _current)
    {
        center_stacked_->setCurrentIndex(next_index);
    });

    animation_group->start(QAbstractAnimation::DeleteWhenStopped);
}

void GameWindow::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);

    painter.setPen(Qt::transparent);
    painter.setBrush(QColor(201, 165, 131));

    painter.drawRect(0, 0, width(), height());

    painter.setBrush(QColor(153, 126, 99));
    painter.drawRect(center_stacked_->geometry().x() + 8,
                     center_stacked_->geometry().y() + 8,
                     center_stacked_->geometry().width(),
                     center_stacked_->geometry().height());
}

void GameWindow::showEvent(QShowEvent *event) {
    QMargins margins = layout()->contentsMargins();
    int width = chess_panel_->sizeHint().width() + margins.left() + margins.right();
    display_panel_->setFixedHeight(chess_panel_->sizeHint().height() * 0.45);
    int height = chess_panel_->height() + display_panel_->height() + margins.top() + margins.bottom();
    setFixedSize(width, height);

    if (SCORE_RECORD->hasRecord())
    {
        SCORE_RECORD->loadRecord();
    }
    else
    {
        SCORE_RECORD->initRecord();
    }
    chess_panel_->loadChess();
}
